package com.cskaoyan.javase.oop1._11static._2compare;

/**
 *
 * 我们从以下四个角度比较（拿成员变量为例）
 *      1.成员的所属
 *          成员变量: 属于对象的,必须创建对象,才能够访问成员变量
 *          静态成员变量: 属于类的,可以直接通过类名点访问
 *
 *      2.在内存中的位置
 *          成员变量: 堆上的对象中
 *          静态成员变量: 堆上一片被全体对象所共享的区域
 *
 *      3.在内存中出现的时间
 *          成员变量: 必须在创建对象之后,才会存在
 *          静态成员变量: 只要类加载完成,静态成员变量就存在了
 *              显然静态成员变量先存在,成员变量之后存在
 *
 *      4.调用方式
 *          成员变量: 对象名点
 *          静态成员变量: 可以用对象名点,但是这种方式不合适,禁止这么做
 *              应该用类名点访问
 *
 * 以上是静态成员变量和成员变量的区别,静态成员方法也有类似的区别
 *
 * 静态成员在类加载完毕以后就存在了,普通成员在创建对象之后才会存在
 * 类加载在前,创建对象在后
 * 类加载不一定创建对象,还可能有其它方式触发类加载
 * 但是创建对象,一定完成了类加载
 * 所以对于以下问题:
 *      1.静态成员方法中,能够访问普通成员吗?
 *          不能的,因为类加载之后,完全可能没有对象,没有对象就没有普通成员
 *          如果一定要访问,需要自己手动创建对象,然后再访问
 *      2.在成员方法中,能够访问静态成员吗?
 *          可以,因为一旦创建对象,类加载肯定完成了
 *          静态成员早就已经存在了,当然可以访问
 *
 *  总之,要搞清楚,类加载在前,创建对象在后.
 *
 *  构造器中能不能访问静态成员?
 *  肯定可以,构造器是在创建对象中被调用,这时静态成员也已经存在了.
 *
 *  当然,静态成员变量的赋值,是完全可以依赖于普通成员方法和构造器的,而且依赖于创建对象赋值
 *          肯定会覆盖类加载过程中的赋值
 *
 *
 * @since 10:42
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*
            以下访问只会触发Student类的类加载
            所以只存在默认初始化和显式赋值两个过程
            num = 100;
         */
        System.out.println(Student.staticNum);
        Student s = new Student();

        /*
            创建对象在类加载之后
            静态成员变量如果依赖于创建对象赋值
            那么它的赋值一定是最终的
         */
        System.out.println(Student.staticNum);

        s.test();

        System.out.println(Student.staticNum);

    }
}

class Student {
    static int staticNum = 100;
    int num;

    public void test() {
  /*      System.out.println(num);
        System.out.println(staticNum);*/
        staticNum = 200;
        // testStatic();
    }

    public static void testStatic() {
        Student s = new Student();
        System.out.println(s.num);
        // System.out.println(num);
    }

    public Student() {
       staticNum = 1000;
    }
}
